/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2018年7月12日
 * V4.0
 */
package com.jphenix.driver.log.xlogc;

import com.jphenix.share.tools.Base64;

import java.util.ArrayList;
import java.util.List;

/**
 * 日志信息数据循环存储VO
 * @author MBG
 * 2018年7月12日
 */
public class LogEventAroundVO {

	private long         lastPushTime = 0;                        //上次放入信息的时间
	private int          elementCount = 1000;		              //循环元素个数（信息堆栈深度）
    private int          taskPoint    = 0;			              //元素指针
    private long         intervalTime = 0;		                  //间隔时间
    private String       serverName   = null;                     //当前服务器名
    private String       groupName    = null;                     //当前服务器所属分组名
    private List<String> elementList  = new ArrayList<String>();  //元素序列                  ele:日志内容字符串
    private List<Long>   timeList     = new ArrayList<Long>();    //元素时间戳序列      ele:日志时间戳
    
	/**
	 * 构造函数
	 * @author 马宝刚
	 */
	public LogEventAroundVO() {
		super();
	}
	
	/**
	 * 设置集群信息
	 * @param serverName  当前服务器名
	 * @param groupName   当前服务器所属分组名
	 * 2018年7月17日
	 * @author MBG
	 */
	public void setCluster(String serverName,String groupName) {
		this.serverName = serverName;
		this.groupName  = groupName;
	}
	
	/**
	 * 添加日志信息
	 * @param content 任务数据字符串
	 * 2016年7月4日
	 * @author MBG
	 */
	public synchronized void addLog(String content) {
	    lastPushTime = System.currentTimeMillis();
		if(elementList.size()>=elementCount) {
			elementList.set(taskPoint,content);
			timeList.set(taskPoint,lastPushTime);
		}else {
			elementList.add(taskPoint,content);
			timeList.add(taskPoint,lastPushTime);
		}
		taskPoint++;
		if(taskPoint>=elementCount) {
			taskPoint = 0;
		}
	}

	
	/**
	 * 获取日志
	 * @param ts            日志起始时间戳
	 * @param isLocal       是否本机接受获取日志请求（而不是集群中其它服务器发起获取日志请求）
	 * @return              日志内容
	 * 2018年7月17日
	 * @author MBG
	 */
	public String getLog(long ts,boolean isLocal) {
	    //符合条件的信息序列
		List<String> logList = new ArrayList<String>();
		//先保存下来元素总大小，防止在以下处理过程中，该值发生变化
		int eleSize = elementList.size();
		if(ts<1) {
			ts = System.currentTimeMillis();
		}else if(elementList.size()>0){
			ts++; //加1毫秒，避免获取到上一次记录
			String log;   //日志元素
			long   logTs; //对应的时间戳
			if(elementCount>eleSize) {
				//还没有进行循环存储
				//获取最后一个元素
				for(int i=0;i<eleSize;i++) {
					log   = elementList.get(i);
					logTs = timeList.get(i);
					if(log==null || log.length()<1) {
						continue;
					}
					if(logTs>=ts) {
						ts = logTs;
						logList.add(log);
					}
				}
			}else {
				int thisPoint = taskPoint; //当前循环指针
				boolean isFirst = true;	//是否首次循环
				int around = 0; //周期指针
				boolean inData = false; //是否获取到数据
				while(isFirst || (thisPoint!=taskPoint)) {
					isFirst = false;
					around++;
					if(around>elementCount) {
						break;
					}
					if(thisPoint>=elementCount) {
						thisPoint = 0;
					}
					log   = elementList.get(thisPoint); //获取最后一个元素
					logTs = timeList.get(thisPoint);    //对应的时间戳
					thisPoint++;
					if(logTs>=ts) {
						inData = true;
						logList.add(log);
						ts = logTs;
					}else {
						if(inData) {
							break;
						}
					}
				}
			}
		}
		//构建返回值
		StringBuffer reSbf = new StringBuffer();
		if(logList.size()<1) {
			ts = System.currentTimeMillis();
		}
		reSbf
			.append("fixLogData({'local':'").append(isLocal?"1":"0").append("','_ts':'")
			.append(ts)
			.append("','_intervaltime':'")
			.append(intervalTime);
		if(groupName!=null) {
			reSbf.append("','group':'").append(groupName).append("','server':'").append(serverName);
		}
		reSbf.append("','element':[");
		boolean noFirst = false; //是否不是首次循环
		for(String ele:logList) {
			if(noFirst) {
				reSbf.append(",");
			}else {
				noFirst = true;
			}
			reSbf.append("'").append(Base64.base64Encode(ele,"UTF-8")).append("'");
		}
		reSbf.append("]});");
		return reSbf.toString();
	}
	

	
	/**
	 * 覆盖方法
	 */
	@Override
    public String toString() {
	    //构造返回值
	    StringBuffer reSbf = new StringBuffer();
	    reSbf
	        .append("lastPushTime:[")
	        .append(lastPushTime)
	        .append("] taskPoint:[")
	        .append(taskPoint)
	        .append("] elementCount:[")
	        .append(elementCount)
	        .append("] elementSize:[")
	        .append(elementList.size())
	        .append("]");
	    //不现实详细内容，因为如果元素量过大，会导致输出过多内容
	    return reSbf.toString();
	}
}
